package binbaum;

import java.util.ArrayList;
import java.util.Scanner;

/**Diese Klasse betrachtet die in der Klasse Wrapper definierte Instanz namens
 * referenz als funktionierenden Suchbaum, mit dessen Hilfe sie einen fremden
 * Suchbaum testet.
 * Die sonstigen nötigen Anpassungen der zu testenden Klasse erfolgen in der
 * Hilfsklassw Wrapper.
 */
public class BaumTest{
  /**Erzeugt selber einen Satz von Testdaten, wenn mit Argumenten aufgerufen:
   *   java BaumTest 100 id
   *   wobei die Werte 0...99 gemischt geinserted (i) und in anderer Reihenfolge
   *   deleted (d) werden.
   * Oder liest eine Datei mit Befehlen von der Tastatur ein
   *   java BaumTest
   * Diese muss gefüllt werden mit 'i' und einer Zahlenmenge oder 'd' und
   * einer Zahlenmenge. Alles andere führt zum Ende.
   */
  public static void main(String[] args){
    ArrayList<Integer> zahlen=new ArrayList<Integer>(100);
    if(args.length>0){
      int anz=Integer.parseInt(args[0]);
      // Erzeuge verschiedene Werte.
      for(int i=0; i<anz; i++) zahlen.add(i);
      mischen(zahlen);
      if(args[1].contains("i")) testinsert(zahlen);
      if(args[1].contains("d")){
        mischen(zahlen);// andere Reihenfolge als bei insert
        testdelete(zahlen);
      }
    } else{// Zahlen von Tastatur holen
      Scanner tastatur=new Scanner(System.in);
      String job;
      while(tastatur.hasNext() && "id".contains(job=tastatur.next())){
        zahlen.clear();
        while(tastatur.hasNextInt()) zahlen.add(tastatur.nextInt());
        if("i".equals(job)) testinsert(zahlen);
        if("d".equals(job)) testdelete(zahlen);
      }
    }
    System.out.println("Folgende Werte sind noch im Baum:");
    System.out.println(Wrapper.zutesten);
  }

  public static void mischen(ArrayList<Integer> zahlen){
    int anz=zahlen.size();
    for(int i=0; i<anz; i++){
      Integer z=zahlen.remove(i);
      zahlen.add((int)(Math.random()*anz), z);
    }
  }

  public static void testinsert(ArrayList<Integer> zahlen){
    ausgabe(zahlen, "Einzufügende Zahlen:");
    for(int z: zahlen){
      System.out.println("Füge "+z+" ein:");
      Wrapper.rinsert(z);
      Wrapper.insert(z);
      if(baumEquals(Wrapper.getRWurzel().rson(), Wrapper.getWurzel().rson()))
        System.out.println("...korrekt");
      else System.out.println("...hat zu obigem Fehler geführt!");
    }
  }

  public static void testdelete(ArrayList<Integer> zahlen){
    ausgabe(zahlen, "Zu löschen:");
    for(int z: zahlen){
      System.out.println("Entferne "+z+":");
      Wrapper.rdelete(z);
      Wrapper.delete(z);
      if(baumEquals(Wrapper.getRWurzel().rson(), Wrapper.getWurzel().rson()))
        System.out.println("...korrekt");
      else System.out.println("...hat zu obigem Fehler geführt!");
    }
  }

  public static void ausgabe(ArrayList<Integer> zahlen, String text){
    System.out.println(text);
    for(int z: zahlen) System.out.print(z+" ");
    System.out.println();
  }

  public static boolean baumEquals(IBinKnoten goodroot, IBinKnoten testroot){
    if(goodroot==null) // kein Eintrag wird erwartet
      if(testroot==null) return true;
      else System.out.println("Falscher Eintrag: "+testroot.datum());
    else // ein Eintrag wird erwartet
      if(testroot!=null)
        if(goodroot.datum()==testroot.datum()) return
            baumEquals(goodroot.lson(), testroot.lson())
            && baumEquals(goodroot.rson(), testroot.rson());
        else System.out.println(
            "Statt "+testroot.datum()+" wäre "+goodroot.datum()+ "richtig");
      else System.out.println("Fehlender Eintrag: "+goodroot.datum());
    return false;
  }
}
